home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Apple Macintosh Developer Technical Support
- **
- ** Sample showing how to print clipped offscreens.
- **
- ** by Tim Carroll and Ingrid Kelly, Apple Developer Technical Support
- **
- ** File: Offscreen Region.c
- **
- ** Copyright ©1996 Apple Computer, Inc.
- ** All rights reserved.
- **
- ** 2/94 v. 1.0 Shipped as 'Offscreen region MaskRgn' sample.
- ** 11/96 v. 2.0 Rewritten as 'Print clipped offscreen' to fix
- ** problems printing to PostScript printers (changed
- ** maskRgn to clipping the region before sending to the
- ** printing port since PS printers don't support maskRgn)
- **
- ** You may incorporate this sample code into your applications without
- ** restriction, though the sample code has been provided "AS IS" and the
- ** responsibility for its operation is 100% yours. However, what you are
- ** not permitted to do is to redistribute the source as "Apple Sample
- ** Code" after having made changes. If you're going to re-distribute the
- ** source, we require that you make it clear in the source that the code
- ** was descended from Apple Sample Code, but that you've made changes.
- */
-
- /**------------------------------------------------------------------------------------**
- Print clipped offscreen: Takes a text string, turns it into a region and
- copies a clipped bitmap (just a pattern in this case, but it could be
- anything) to the printing grafPort. The effect is patterned text here,
- but any image could be showing through the text.
-
- You can also see the clipped image on the screen by turning on DrawStuffToScreen.
- Do this with qdToScreen below.
-
- This sample is a rewrite of the 'Offscreen region MaskRgn' sample.
-
- **-----------------------------------------------------------------------------------**/
-
- /*************************************************************************************
- #
- # CONDITIONALS
- #
- # There are a number of conditionals used to control exactly how the code runs.
- #
- #
- # qDebugging -- Whether or not additional debugging code should be inserted. With this
- # turned on, most errors will DebugStr almost immediately and return errors as the error
- # propagates up the calling chain. This is slower, but if you've found a weird bug,
- # this is the fastest way to replicate it.
- #
- # qdToScreen -- if this is set to 1, we draw to the screen instead of to the printer.
- #
- *************************************************************************************/
-
- #define qDebugging 1
- #define qdToScreen 0
-
-
- /*********************************************************************************
- # ERROR HANDLING MACROS
- #
- # These macros can be used to implement nice error handling within a function.
- # Essentially, all errors jump to an error handler at the end of the function, which
- # should cleanup any leftovers and return the appropriate error result.
- #
- # Note that the error handlers take a message string. This should be a good
- # indication of the actual error, and it will appear when debugging is turned on.
- #
- # Note that any additional sanity checking code can be added to any function by using
- #
-
- #if qDebugging
- // do additional sanity checking here.
- #endif
- #
- # For example, this could be used to check the internal validity of an object before
- # taking an action.
- #
- *********************************************************************************/
-
- #ifndef qDebugging
- #define qDebugging 0
- #endif
-
- #if qDebugging
- #define SIGNAL_ERROR(msg) {DebugStr(msg); goto error;}
- #else
- #define SIGNAL_ERROR(msg) {goto error;}
- #endif
-
- #define FAIL_NIL(y,msg) if (y == NULL) SIGNAL_ERROR(msg)
- #define FAIL_OSERR(y,msg) if (y != noErr) SIGNAL_ERROR(msg)
- #define FAIL_FALSE(y,msg) if (!y) SIGNAL_ERROR(msg)
-
-
-
- #include <Printing.h>
- #include <QDOffscreen.h>
-
- void main (void);
- OSStatus PrintStuff (void);
- OSStatus DrawStuff (Rect theWorld);
- OSStatus PrepareOffScreens(void);
- OSStatus KillOffscreens(void);
- OSStatus DrawStuffToScreen(void);
-
- /*------ globals --------------------------------------------------------------------------*/
-
- GWorldPtr gMaskOffscreen = NULL, gImageOffscreen = NULL;
- RgnHandle gMaskRegion = NULL;
- Rect gBoundsRect;
-
- /*------ main ----------------------------------------------------------------------------*/
- // All main does is the standard mac init, followed by initializing the offscreens
- // and printing.
- /*----------------------------------------------------------------------------------------*/
-
- void main(void)
- {
- OSStatus theErr = noErr;
-
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
-
- theErr = PrepareOffScreens();
- FAIL_OSERR (theErr, "\pError: Failed to prepare the offscreen environment")
-
- #if qdToScreen
- DrawStuffToScreen();
- while (!Button());
- #else
- PrintStuff ();
- #endif
-
- error:
- theErr = KillOffscreens();
-
- } /* main */
-
-
- /*------ PrepareOffScreens ---------------------------------------------------------------*/
- // PrepareOffScreens sets up the GWorlds and does the actual text clipping.
- /*----------------------------------------------------------------------------------------*/
-
- OSStatus PrepareOffScreens()
- {
- OSStatus theErr = noErr;
- CGrafPtr savePort;
- GDHandle saveDevice;
- short fontNum;
- PixPatHandle image = NULL;
- PixMapHandle thePix = NULL;
-
- SetRect(&gBoundsRect,0,0,700,700);
- GetGWorld(&savePort,&saveDevice);
-
- /* Create the offscreen mask */
-
- theErr = NewGWorld(&gMaskOffscreen, 1, &gBoundsRect, NULL, NULL, 0);
- FAIL_OSERR (theErr, "\pError: Failed to create mask GWorld")
- FAIL_NIL (gMaskOffscreen, "\pError: Failed to create mask GWorld")
-
- thePix = GetGWorldPixMap (gMaskOffscreen);
- FAIL_NIL (thePix, "\pError: Failed to retrieve mask pixmap")
- FAIL_FALSE (LockPixels(thePix), "\pError: Failed to lock the mask pixmap")
-
- SetGWorld(gMaskOffscreen,NULL);
- ClipRect(&gBoundsRect);
-
- ForeColor(blackColor);
- EraseRect(&gBoundsRect);
- GetFNum("\pTimes",&fontNum);
- TextFont(fontNum);
- TextFace(bold);
- TextSize(60);
- MoveTo(10,100);
- DrawString("\pHere’s our string test");
-
- SetGWorld (savePort,saveDevice);
-
- /* OK, the mask pixmap now has our string in it. Let's make a region from it. */
-
- gMaskRegion = NewRgn();
- theErr = QDError();
- FAIL_OSERR (theErr, "\pError: Failed to create the mask region")
- FAIL_NIL (gMaskRegion,"\pError: Failed to create the mask region")
-
- theErr = BitMapToRegion(gMaskRegion,&((GrafPtr)gMaskOffscreen)->portBits);
- FAIL_OSERR (theErr, "\pError: Failed to convert the mask to a region")
-
- UnlockPixels (thePix);
-
-
- /* Build the offscreen pixmap that we'll draw to the printer */
-
- theErr = NewGWorld(&gImageOffscreen, 8, &gBoundsRect, NULL, NULL, 0);
- FAIL_OSERR (theErr, "\pError: Failed to create image GWorld")
- FAIL_NIL (gImageOffscreen, "\pError: Failed to create image GWorld")
-
- thePix = GetGWorldPixMap (gImageOffscreen);
- FAIL_NIL (thePix, "\pError: Failed to retrieve image pixmap")
- FAIL_FALSE (LockPixels(thePix), "\pError: Failed to lock the image pixmap")
-
- /* We erase the image, then we use the mask clipping region and draw a color
- pattern to the pixmap */
-
- image = GetPixPat(16);
- FAIL_NIL (image, "\pError: Failed to load the pixel pat")
-
- SetGWorld(gImageOffscreen,NULL);
- ClipRect (&gBoundsRect);
- EraseRect (&gBoundsRect);
-
- SetClip(gMaskRegion);
-
- FillCRect(&gBoundsRect, image);
-
- // restore the clip rect
- ClipRect (&gBoundsRect);
- UnlockPixels(thePix);
-
- // Cleanup and return noErr;
- goto cleanup;
-
- error:
- if (theErr == noErr)
- theErr = paramErr;
-
- cleanup:
- SetGWorld (savePort, saveDevice);
- if (image != NULL)
- DisposePixPat(image);
-
- return theErr;
- }
-
- /*------ DrawStuff -----------------------------------------------------------------------*/
- // DrawStuff CopyBits from the offscreen into the printer/window port.
- /*----------------------------------------------------------------------------------------*/
-
- OSStatus DrawStuff (Rect theRect)
- {
- OSStatus theErr = noErr;
- GrafPtr currentPort;
- PixMapHandle offscreenPix;
-
- /* Here's where we use CopyBits to copy from gImageOffscreen to the printer/window port */
-
- GetPort(¤tPort);
-
- offscreenPix = GetGWorldPixMap(gImageOffscreen);
- FAIL_NIL (offscreenPix, "\pError: Failed to retrieve image pixmap")
- FAIL_FALSE (LockPixels(offscreenPix), "\pError: Failed to lock the image pixmap")
-
- CopyBits((BitMap*)*offscreenPix,
- &(currentPort)->portBits,
- &gBoundsRect, &gBoundsRect, srcCopy, NULL);
-
- UnlockPixels(offscreenPix);
-
- goto cleanup;
-
- error:
- if (theErr == noErr)
- theErr = paramErr;
- cleanup:
- return theErr;
- } /* DrawStuff */
-
- /*------ PrintStuff ----------------------------------------------------------------------*/
- // PrintStuff performs the generic printing calls for printing to the Macintosh Printing
- // Manager.
- // Sets the current port to the printer port.
- /*----------------------------------------------------------------------------------------*/
-
- OSStatus PrintStuff ()
- {
- OSStatus theErr = noErr;
- GrafPtr oldPort;
- THPrint thePrRecHdl;
- TPPrPort thePrPort;
- TPrStatus theStatus;
-
- GetPort(&oldPort);
-
- thePrRecHdl = (THPrint) NewHandle (sizeof (TPrint));
- theErr = MemError();
- FAIL_OSERR( theErr, "\pError: Failed to allocate a TPrint record")
- FAIL_NIL (thePrRecHdl, "\pError: Failed to allocate a TPrint record")
-
- PrOpen(); //The PrOpen procedure prepares the current printer driver for use.
- theErr = PrError();
- FAIL_OSERR (theErr, "\pError: Failed to open the printer driver")
-
- PrintDefault(thePrRecHdl);
- PrValidate(thePrRecHdl);
- theErr = PrError();
- FAIL_OSERR (theErr, "\pError: Failed to create a valid print record")
-
- if (! PrStlDialog(thePrRecHdl))
- goto cleanup; // user cancelled
-
- if (! PrJobDialog(thePrRecHdl))
- goto cleanup; // user cancelled
-
- thePrPort = PrOpenDoc(thePrRecHdl, nil, nil);
- theErr = PrError();
-
- if (theErr == noErr)
- {
- PrOpenPage(thePrPort, nil);
- theErr = PrError();
-
- if (theErr == noErr)
- {
- // Finally, we're ready to draw!
- DrawStuff ((**thePrRecHdl).prInfo.rPage);
- PrClosePage(thePrPort);
- }
-
- PrCloseDoc(thePrPort);
- }
-
- theErr = PrError();
- FAIL_OSERR (theErr, "\pError: Document failed to print")
-
- if ((((TPPrint)*thePrRecHdl)->prJob.bJDocLoop == bSpoolLoop))
- PrPicFile(thePrRecHdl, nil, nil, nil, &theStatus);
-
- goto cleanup;
-
- error:
- if (theErr == noErr)
- theErr = paramErr;
-
-
- cleanup:
- SetPort(oldPort);
- PrClose();
- if (thePrRecHdl)
- DisposeHandle ((Handle) thePrRecHdl);
-
- return theErr;
- } /* PrintStuff */
-
- /*------ KillOffscreens ------------------------------------------------------------------*/
- // KillOffscreens cleans up the offscreens.
- /*----------------------------------------------------------------------------------------*/
-
- OSStatus KillOffscreens()
- {
- if (gMaskOffscreen)
- DisposeGWorld(gMaskOffscreen);
- if (gImageOffscreen)
- DisposeGWorld(gImageOffscreen);
- if (gMaskRegion)
- DisposeRgn(gMaskRegion);
-
- return noErr;
- } /* KillOffscreens */
-
- /*------ DrawStuffToScreen ------------------------------------------------------------------*/
- // DrawStuffToScreen sets up the window port.
- // Sets the current port to the window port.
- /*----------------------------------------------------------------------------------------*/
-
- OSStatus DrawStuffToScreen(void)
- {
- WindowRef theWindow = NULL;
- Rect bounds = gBoundsRect;
- OSStatus theErr = noErr;
- GrafPtr savePort;
-
- GetPort (&savePort);
-
- OffsetRect (&bounds, 30,30);
- theWindow = NewCWindow(NULL, &bounds, "\pFoo", true, 0, (WindowRef)-1, false, 0);
- FAIL_NIL (theWindow, "\pError: Failed to create the window")
-
- SetPortWindowPort (theWindow);
- theErr = DrawStuff(gBoundsRect);
-
- goto cleanup;
-
- error:
- if (theErr == noErr)
- theErr = paramErr;
-
- cleanup:
- SetPort (savePort);
-
- return theErr;
- } /* DrawStuffToScreen */